<!--
 * @Description: 前置任务
 * @Author: wind-lc
 * @version: 1.0
 * @Date: 2021-11-02 20:54:48
 * @LastEditTime: 2023-06-05 14:32:17
 * @FilePath: \cscec-pms-admin\src\views\construction\constructionSchedule\components\PredecessorTask.vue
-->
<template>
  <BaseModal
    :visible="visible"
    title="设置前置任务"
    :width="1200"
    destroy-on-close
    @cancel="handleModalCancel"
  >
    <template slot="footer">
      <a-button @click="handleModalCancel" :disabled="loading">
        取消
      </a-button>
    </template>
    <custom-form
      ref="form"
      :is-validate="true"
      :edit-model="''"
      :form="form"
      :form-list="formOption"
    />
    <a-button
      type="primary"
      style="margin-bottom:20px;"
      :disabled="active"
      @click="handleAdd"
    >
      增行
    </a-button>
    <a-table
      ref="table"
      :columns="columns2"
      :data-source="data"
      :pagination="false"
      bordered
      :loading="loading"
      row-key="frontTaskId"
      :scroll="{ y: 300 }"
    >
      <template
        slot="nodeType"
        slot-scope="text,record"
      >
        <a-select
          v-if="record.update"
          v-model="record.nodeType"
          placeholder="请选择前置节点类型"
          class="width-100"
          @change="handleComputeIntervalDay(record)"
        >
          <a-select-option
            v-for="{value,label} in nodeTypeList"
            :key="value"
            :value="value"
          >
            {{ label }}
          </a-select-option>
        </a-select>
        <template v-else>
          {{ nodeTypeList.find(el=>el.value ===record.nodeType).label }}
        </template>
      </template>
      <template
        slot="sortNum"
        slot-scope="text,record"
      >
        <a-select
          v-if="record.update"
          v-model="record.frontNodeId"
          placeholder="请选择节点序号"
          class="width-100"
          show-search
          :filter-option="filterOption"
          @change="((value,option)=>{handleSortNumChange(value,option,record)})"
        >
          <a-select-option
            v-for="{id,sortNum,planStartTime,planEndTime} in sortNumList"
            :key="id"
            :value="id"
            :data="{planStartTime,planEndTime}"
          >
            {{ sortNum }}
          </a-select-option>
        </a-select>
        <template v-else>
          {{ record.sortNum }}
        </template>
      </template>
      <template
        slot="frontNodeName"
        slot-scope="text,record"
      >
        <a-tree-select
          v-if="record.update"
          v-model="record.frontNodeId"
          placeholder="请选择节点名称"
          class="width-100"
          :tree-data="frontNodeNameTree"
          :replace-fields="replaceFields"
          show-search
          :filter-tree-node="filterTreeNode"
          @change="(value, label, extra)=>{handleFrontTaskNameChange(value, label, extra,record)}"
        />
        <template v-else>
          {{ record.frontNodeName }}
        </template>
      </template>
      <template
        slot="intervalDay"
        slot-scope="text,record"
      >
        <BaseInput
          v-if="record.update"
          v-model="record.intervalDay"
          placeholder="请输入间隔时间"
        />
        <template v-else>
          {{ record.intervalDay }}
        </template>
      </template>
      <template
        slot="operation"
        slot-scope="text,record"
      >
        <template v-if="record.update">
          <a-button
            type="link"
            :disabled="record.disabled"
            class="predecessor-task-btn"
            @click="handleUpdate(record)"
          >
            保存
          </a-button>
          <a-divider type="vertical" />
          <a-button
            type="link"
            :disabled="record.disabled"
            class="predecessor-task-btn"
            @click="handleCancel(record)"
          >
            取消
          </a-button>
        </template>
        <template v-else>
          <a-button
            type="link"
            :disabled="record.disabled"
            class="predecessor-task-btn"
            @click="handleUpdate(record)"
          >
            编辑
          </a-button>
          <a-divider type="vertical" />
          <a-button
            type="link"
            :disabled="record.disabled"
            class="predecessor-task-btn"
            @click="handleDelete(record)"
          >
            删除
          </a-button>
        </template>
      </template>
    </a-table>
  </BaseModal>
</template>
<script>
import BaseModal from '@/components/BaseModal'
import { columns2, nodeTypeList } from '../model.js'
import { TreeSelect } from 'ant-design-vue'
export default {
  name: 'PredecessorTask',
  props: {
    // 隐藏显示
    visible: {
      type: Boolean,
      require: true
    },
    // 业务事项
    record: {
      type: Object,
      require: true
    },
    // 接口对象包含五个接口
    api: {
      type: Object,
      default: ()=>{}
    }
  },
  components: {
    BaseModal,
    ATreeSelect: TreeSelect
  },
  data() {
    return {
      //表单
      form: {},
      // 表头
      columns2,
      //表格数据
      data: [],
      // 前置节点类型
      nodeTypeList,
      // 节点序号列表
      sortNumList: [],
      // 节点名称树
      frontNodeNameTree: [],
      // 节点名称树字体替换
      replaceFields: {
        children: 'childTree',
        title: 'nodeName',
        key: 'id',
        value: 'id'
      },
      // 表格加载及查询
      loading: false,
      // 表格激活中
      active: false
    }
  },
  computed: {
    // 表单配置
    formOption() {
      return [
        {
          label: '节点序号',
          keyName: 'sortNum',
          type: 'BaseInput',
          disabled: true,
          span: 12
        },
        {
          label: '节点名称',
          keyName: 'businessMatters',
          type: 'BaseInput',
          disabled: true,
          span: 12
        },
        {
          label: '计划开始时间',
          keyName: 'planStartTime',
          type: 'BaseInput',
          disabled: true,
          span: 12
        },
        {
          label: '计划完成时间',
          keyName: 'planEndTime',
          type: 'BaseInput',
          disabled: true,
          span: 12
        }
      ]
    }
  },
  watch: {
    visible: {
      handler(newV, oldV) {
        if (newV) {
          this.getData()
        }
      }
    }
  },
  methods: {
    /**
     * @description: 获取表格数据
     * @param {void}
     * @return {void}
     */
    getData() {
      this.loading = true
      this.api.queryFrontTask(this.record.id)
        .then(({ code, data: { currentNodeName, currentNodePlanEndTime, currentNodePlanStartTime, currentNodeSortNum, frontTaskList } }) => {
          if (code === 200) {
            this.data = frontTaskList.map((el) => {
              el.update = false
              el.disabled = false
              return el
            })
            this.form = {
              sortNum: currentNodeSortNum,
              businessMatters: currentNodeName,
              planStartTime: currentNodePlanStartTime,
              planEndTime: currentNodePlanEndTime
            }
          } else {
            this.data = []
          }
        })
        .finally(() => {
          this.loading = false
          this.active = false
        })
    },
    /**
     * @description: 关闭模态框
     * @param {void}
     * @return {void}
     */
    handleModalCancel() {
      // 数据未请求完成时不触发
      if(!this.loading){
        this.$emit('update:visible', false)
        this.$emit('changeFrontTask', this.$clone(this.data))
        this.data = []
      }
    },
    /**
     * @description: 获取前置任务节点名称树
     * @param {void}
     * @return {void}
     */
    async getFrontTaskTree(frontTaskId = undefined) {
      this.loading = true
      const {
        code,
        data: { sortNumVO, treeList }
      } = await this.api.queryFrontTaskTree({
        currentNodeId: this.record.id,
        frontTaskId
      })
      if (code === 200) {
        this.sortNumList = sortNumVO
        this.frontNodeNameTree = treeList
      }
      this.loading = false
    },
    /**
     * @description: 新增行
     * @param {void}
     * @return {void}
     */
    handleAdd() {
      this.active = true
      this.data.map((el) => {
        el.disabled = true
        return el
      })
      this.data.push({
        frontTaskId: 'newId',
        nodeType: void 0,
        frontNodeId: void 0,
        sortNum: void 0,
        frontNodeName: void 0,
        intervalDay: void 0,
        update: true,
        disabled: false,
        nodeInfo: {}
      })
      this.getFrontTaskTree()
    },
    /**
     * @description: 下拉框搜索过滤
     * @param {string} input 输入值
     * @param {object} option 下拉对象
     * @return {boolean} 是否符合过滤条件
     */
    filterOption(input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
    /**
     * @description: 下拉树形框搜索过滤
     * @param {string} input 输入值
     * @param {object} option 下拉对象
     * @return {boolean} 是否符合过滤条件
     */
    filterTreeNode(input, treeNode) {
      return treeNode.componentOptions.propsData.title.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
    /**
     * @description: 计算间隔时间
     * @param {object} record 行数据
     * @return {void}
     */
    handleComputeIntervalDay(record) {
      // 前置节点
      const {
        nodeType,
        nodeInfo: { planStartTime: startTime, planEndTime: endTime }
      } = record
      // 当前节点
      const { planStartTime, planEndTime } = this.record
      switch (nodeType) {
        case 'FS':
          if ((planStartTime ?? '' !== '') && (endTime ?? '' !== '')) {
            record.intervalDay = this.moment(planStartTime).diff(this.moment(endTime), 'days')
          }
          break
        case 'FF':
          if ((planEndTime ?? '' !== '') && (endTime ?? '' !== '')) {
            record.intervalDay = this.moment(planEndTime).diff(this.moment(endTime), 'days')
          }
          break
        case 'SF':
          if ((planEndTime ?? '' !== '') && (startTime ?? '' !== '')) {
            record.intervalDay = this.moment(planEndTime).diff(this.moment(startTime), 'days')
          }
          break
        case 'SS':
          if ((planStartTime ?? '' !== '') && (startTime ?? '' !== '')) {
            record.intervalDay = this.moment(planStartTime).diff(this.moment(startTime), 'days')
          }
          break
      }
    },
    /**
     * @description: 节点序号改变关联节点名称
     * @param {string} value 选中id
     * @param {object} oiption 节点虚拟dom
     * @param {object} record 行数据
     * @return {void}
     */
    handleSortNumChange(value, oiption, record) {
      const { planStartTime, planEndTime } = oiption.data.attrs.data
      record.nodeInfo = {
        planStartTime,
        planEndTime
      }
      this.handleComputeIntervalDay(record)
    },
    /**
     * @description: 节点名称改变关联节点序号
     * @param {string} value 选中id
     * @param {string} label 选中项label
     * @param {object} extra 选中节点
     * @param {object} record 行数据
     * @return {void}
     */
    handleFrontTaskNameChange(value, label, extra, record) {
      const { planStartTime, planEndTime } = extra.triggerNode._props.dataRef
      record.nodeInfo = {
        planStartTime,
        planEndTime
      }
      this.handleComputeIntervalDay(record)
    },
    /**
     * @description: 编辑/新增
     * @param {object} record 行数据
     * @return {void}
     */
    handleUpdate(record) {
      if (record.update) {
        const { frontTaskId, frontNodeId, intervalDay, nodeType } = record
        if ((frontTaskId ?? '') !== '' && (frontNodeId ?? '') !== '' && (intervalDay ?? '') !== '' && (nodeType ?? '') !== '') {
          this.loading = true
          if (frontTaskId === 'newId') {
            // 新增
            this.api.createFrontTask({
              currentNodeId: this.record.id,
              frontNodeId,
              intervalDay,
              nodeType
            })
              .then(({ code }) => {
                if (code === 200) {
                  this.$message.success('新增成功')
                  record.update = false
                  this.data = this.data.map((el) => {
                    if (el.frontTaskId !== record.frontTaskId) {
                      el.disabled = false
                    }
                    return el
                  })
                  this.getData()
                }
              })
              .finally(() => {
                this.loading = false
              })
          } else {
            // 编辑
            this.api.editFrontTask({
              currentNodeId: this.record.id,
              frontNodeId,
              intervalDay,
              nodeType,
              frontTaskId
            })
              .then(({ code }) => {
                if (code === 200) {
                  this.$message.success('编辑成功')
                  record.update = false
                  this.data = this.data.map((el) => {
                    if (el.frontTaskId !== record.frontTaskId) {
                      el.disabled = false
                    }
                    return el
                  })
                  this.getData()
                }
              })
              .finally(() => {
                this.loading = false
              })
          }
        } else {
          this.$message.warning('前置节点信息不能为空')
        }
      } else {
        // 激活编辑状态
        record.update = true
        this.active = true
        this.data = this.data.map((el) => {
          if (el.frontTaskId !== record.frontTaskId) {
            el.disabled = true
          } else {
            el.disabled = false
          }
          return el
        })
        this.getFrontTaskTree(record.frontTaskId)
      }
    },
    /**
     * @description: 删除
     * @param {object} record 行数据
     * @return {void}
     */
    handleDelete(record) {
      const vm = this
      this.$confirm({
        okText: '确定',
        cancelText: '取消',
        title: '确定删除该前置任务?',
        onOk() {
          const { frontTaskId } = record
          vm.api.deleteFrontTask({
            currentNodeId: vm.record.id,
            frontTaskId
          }).then(({ code }) => {
            if (code === 200) {
              vm.$message.success('删除成功')
              record.update = false
              vm.getData()
            }
          })
        }
      })
    },
    /**
     * @description: 取消
     * @param {object} record 行数据
     * @return {void}
     */
    handleCancel(record) {
      if (record.frontTaskId === 'newId') {
        this.data.pop()
      } else {
        record.update = false
      }
      this.data = this.data.map((el) => {
        el.disabled = false
        return el
      })
      this.active = false
    }
  }
}
</script>
<style lang="less" scoped>
.width-100 {
  width: 100%;
}
.predecessor-task-btn {
  padding: 0;
}
</style>
